package com.bdd.jpa.service.schedule;

import com.bdd.jpa.entity.domain.ScheduleJob;
import com.bdd.jpa.repository.schedule.ScheduleJobRepository;
import com.bdd.jpa.factory.QuartzFactory;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author Bdd
 * @Description
 *      job调用
 * @Date 2019/9/23 15:47
 */
@Service(value = "jobService")
public class JobService {

    @Autowired
    private ScheduleJobRepository scheduleJobRepository;

    @Autowired
    private Scheduler scheduler;

    /**
     * 添加任务
     *
     * @param scheduleJob
     */
    public void addJob(ScheduleJob scheduleJob) throws Exception {

        System.out.println("开始添加任务调度");
        //添加触发调度名称
        TriggerKey triggerKey = getTriggerKey(scheduleJob);
        //设置触发时间
        CronScheduleBuilder cronScheduleBuilder = getCronExpression(scheduleJob);
        //触发建立
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
        //添加作业名称
        JobKey jobKey = getJobKey(scheduleJob);
        //建立作业
        JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class).withIdentity(jobKey).build();
        //传入调度的数据，在QuartzFactory中需要使用
        jobDetail.getJobDataMap().put("scheduleJob", scheduleJob);

        //调度作业
        scheduler.scheduleJob(jobDetail, trigger);

        scheduleJobRepository.save(scheduleJob);
    }


    /**
     * 修改任务
     *
     * @param scheduleJob 任务对象
     * @return
     * @throws SchedulerException
     */
    public String modifyJob(ScheduleJob scheduleJob) throws Exception {
        //获取TriggerKey
        TriggerKey triggerKey = getTriggerKey(scheduleJob);
        JobKey jobKey = getJobKey(scheduleJob);
        if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            //检查cron表达式是否合法
            checkCronExpression(scheduleJob);
            //表达式调度构建器,不立即执行
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()).withMisfireHandlingInstructionDoNothing();
            //按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                    .withSchedule(scheduleBuilder).build();
//            //修改参数
//            if (!trigger.getJobDataMap().get("invokeParam").equals(scheduleJob.getParams())) {
//                trigger.getJobDataMap().put("invokeParam", scheduleJob.getParams());
//            }
            //按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
            scheduleJobRepository.save(scheduleJob);
            return "success";
        } else {
            return "job or trigger not exists";
        }

    }

    /**
     * 删除任务
     *
     * @param scheduleJob
     */
    public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException {
        JobKey jobKey = getJobKey(scheduleJob);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail != null)
            scheduler.deleteJob(jobKey);
            scheduleJobRepository.delete(scheduleJob);
    }


    /**
     * 暂停所有任务
     *
     * @throws SchedulerException
     */
    public void pauseAll() throws SchedulerException {
        scheduler.pauseAll();
    }

    /**
     * 暂停具体的任务
     *
     * @param scheduleJob
     * @throws SchedulerException
     */
    public void pauseJob(ScheduleJob scheduleJob) throws SchedulerException {
        scheduler.pauseJob(getJobKey(scheduleJob));
    }


    /**
     * 恢复所有任务
     *
     * @throws SchedulerException
     */
    public void resumeAll() throws SchedulerException {
        scheduler.resumeAll();
    }

    /**
     * 恢复具体任务
     *
     * @param scheduleJob
     * @throws SchedulerException
     */
    public void resumeJob(ScheduleJob scheduleJob) throws SchedulerException {
        scheduler.resumeJob(getJobKey(scheduleJob));
    }

    /**
     * 任务key
     *
     * @param scheduleJob
     * @return
     */
    private JobKey getJobKey(ScheduleJob scheduleJob) {
        return JobKey.jobKey(scheduleJob.getId() + scheduleJob.getJobType() + scheduleJob.getJobName());
    }


    /**
     * 获取TriggerKey
     * @param scheduleJob
     * @return
     */
    private TriggerKey getTriggerKey(ScheduleJob scheduleJob) {
        return TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobType());
    }

    /**
     * 获取CronScheduleBuilder，并判断cron是否合法
     * @param scheduleJob
     * @return
     * @throws Exception
     */
    private CronScheduleBuilder getCronExpression(ScheduleJob scheduleJob) throws Exception {
        checkCronExpression(scheduleJob);
        return CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
    }

    /**
     * 检查CronExpression格式是否正确
     * @param scheduleJob
     * @throws Exception
     */
    private void checkCronExpression(ScheduleJob scheduleJob) throws Exception {
        if(!CronExpression.isValidExpression(scheduleJob.getCronExpression()))
            throw new Exception("cron 格式不对");
    }

    /**
     * 获取任务状态
     *
     * @param scheduleJob
     * @return
     */
    public String getJobStatus(ScheduleJob scheduleJob) throws SchedulerException {
        TriggerKey triggerKey = getTriggerKey(scheduleJob);
        return scheduler.getTriggerState(triggerKey).name();
    }


}
